package com.mvu.banana.tools;

import java.util.ArrayList;
import java.util.List;

/**
 * Class description...
 *
 * @author gantz
 */
public class JavaMethod {
  protected JavaType _returnType = new JavaType("void");
  protected String _name;
  protected String _params = "";
  protected StringBuilder body = new StringBuilder();
  protected StringBuilder end = new StringBuilder();
  protected boolean _isStatic;
  protected JavaClass javaClass;
  private List<JavaAnnotation> annotations;

  public JavaMethod(JavaClass parent){
    this.javaClass = parent;
  }

  public JavaMethod withName(String... tokens){
    StringBuilder builder = new StringBuilder();
    for(String token : tokens){
      builder.append(token);
    }
    _name = builder.toString();
    return this;
  }

  public JavaMethod withReturnType(String type){
    _returnType = new JavaType(type);
    return this;
  }

  public JavaMethod withReturnType(Class type){
    javaClass.importClass(type);
    _returnType = new JavaType(type);
    return this;
  }

  public void withReturnType(JavaType type) {
    javaClass.importClass(type);
    _returnType = type;
  }

  public String print() {
    StringBuilder builder = new StringBuilder("\n");
    if(annotations != null){
      for(JavaAnnotation a : annotations){
        builder.append("\n  ").append(a.print());
      }
    }
    builder.append("\n  ");
    if(! javaClass._isInterface){
      builder.append("public ");
    }
    if(_returnType != null){// null for constructor
      builder.append(_returnType.name).append(" ");
    }
    builder.append(_name).append("(").append(_params).append(")");
    if(javaClass._isInterface){
      builder.append(";");
    }else{
      builder.append("{\n").append(body.toString())
              .append(end.toString())
              .append("  }");
    }
    return builder.toString();
  }

  public JavaMethod addLine(String... tokens) {
    body.append("    ");
    for(String token : tokens){
      body.append(token);
    }
    body.append(";\n");
    return this;
  }

  public JavaMethod withParameters(Object... paramTypes) {
    _params = constructParameterString(paramTypes);
    return this;
  }

  public JavaMethod asStatic(boolean isStatic) {
    return this;
  }

  private String constructParameterString(Object[] paramTypes) {
    StringBuilder params = new StringBuilder();
    if (paramTypes != null) {
      for (int i = 0; i < paramTypes.length; i++) {
        JavaType type = JavaType.get(paramTypes[i]);
        javaClass.importClass(type);
        if(i > 0){
          params.append(", ");
        }
        params.append(type.name).append(" ").append("p").append(i);
      }
    }
    return params.toString();
  }

  public JavaAnnotation addAnnotation(Class annotationClass) {
    JavaAnnotation annotation = new JavaAnnotation(javaClass, annotationClass);
    getAnnotations().add(annotation);
    return annotation;
  }

  public void addAnnotation(JavaAnnotation annotation) {
    getAnnotations().add(annotation);
  }

  private List<JavaAnnotation> getAnnotations(){
    if(annotations == null){
      annotations = new ArrayList<JavaAnnotation>();
    }
    return annotations;
  }

  public void addLineAtEnd(String line) {
    end.append("    ");
    end.append(line).append(";\n");
  }
}
